#include "fileinfor.h"
#include "../CheckTool/filefilter.h"
#include "DataBase/keywordlib.h"
#include<iostream>
#define MB  1024
const QStringList FileInfor::WarningString={"注意保存","妥善保管","会后收回","此件属工作秘密","严禁通过互联网、手机、微信等传播使用和对外发布"};
const int HeadLimit=50;
const int TailLimit=100;

using namespace Yzty;
FileInfor* FileInfor::_instance=nullptr;

FileInfor* FileInfor::GetInstance(QObject* parent){
    if(FileInfor::_instance==nullptr)
        FileInfor::_instance=new FileInfor(parent);
    return FileInfor::_instance;
}


FileInfor::~FileInfor(){

}

void FileInfor::SubmitInfor(Yzty::ITEMCODE mcode,QVector<Yzty::BaceInfor*>& infors){
    std::lock_guard<std::mutex> glock(this->_mutex);
    this->_infors[mcode]=std::move(infors);
}

const QVector<Yzty::BaceInfor*>& FileInfor::GetItemInfor(Yzty::ITEMCODE icode){
    std::lock_guard<std::mutex> glock(this->_mutex);
    return this->_infors[icode];
}

QVector<Yzty::BaceInfor*>& FileInfor::GetModifiableInfor(Yzty::ITEMCODE icode){
    std::lock_guard<std::mutex> glock(this->_mutex);
    return this->_infors[icode];
}

FileInfor::FileInfor(QObject* parent):QObject (parent){
    this->_infors.resize(int(FileToolCode::NUMS));
 //   _filecnts=QVector<int>(3);
 //   Initcnts();
    this->_hitcnts.store(0);
    this->_checkcnts.store(0);
    this->_filecnts.store(0);
}

void FileInfor::AddFileCheckRecord(Yzty::FileCheckRecord* infors)
{
    _mutex.lock();
    _allinfors.push_back(infors);
//    _filecnts[1]++;
    _checkcnts++;
    _mutex.unlock();

    //消息根据命中率进行分类
    this->ClassifityInfor(infors);
}


void FileInfor::ClassifityInfor(Yzty::FileCheckRecord *record)
{
    static QVector<double> levels{
        0.05,0.35,1.1
    };
    static QVector<QString> lables{
//        "正常","疑似","涉密"
        "正常","命中","疑似"
    };

    auto finfor=Yzty::FileFilter::GetInstance()->GetSelectAblePaths(record->_type)[int(record->_file_id)];
    Yzty::FileRecordInfor* infor=new Yzty::FileRecordInfor(Yzty::FileToolCode(record->GetModelCode()));

    infor->_filepath=finfor.path();
    infor->_filetname=finfor.fileName();
    infor->_filesize=QString::number(finfor.size()*1.0/MB);
//    infor->_filesize=QString::number(finfor.size());
    infor->_filetype=finfor.suffix();
//   infor->_createtime=finfor.birthTime().toString("yyyy-MM-dd hh:mm:ss");
    infor->_createtime=finfor.metadataChangeTime().toString("yyyy-MM-dd hh:mm:ss");
    infor->_lastmodifytime=finfor.lastModified().toString("yyyy-MM-dd hh:mm:ss");
    infor->_filerecord=record;
    infor->_filerecord->_filename_flag=this->File_Secret_Flag(infor->_filerecord->_hitSubstrings);
    infor->_pwlevel = "待鉴定";
    infor->_result="未判定";
    for(auto& pos:record->_key_pos)
        infor->_hits[pos._lib_id]++;

    infor->_hits[-1]=record->_key_pos.size();

        if(_totals==0)  _totals=1;
  /*      int index=int(std::lower_bound(levels.begin(),levels.end(),record->_key_pos.size()*1.0/(_totals+0.01))-levels.begin());
    int t=record->_key_pos.size()*1.0/(_totals+0.01);
    int index;
    if(t>=lables.size())
        index=lables.size()-1;
    else
        index=int(t);
   infor->_result=lables[index];       //评定结果
*/
    _mutex.lock();
    if(FileToolCode(record->GetModelCode())==FileToolCode::FTOTAL)
    {
        this->_fileinfor.push_back(infor);
        if(record->_filename_flag)
            this->_infors[int(FileToolCode::FTOTAL)].push_back(infor);
        if(infor->_hits[-1]){
            _hitcnts++;
   /*         if(infor->_filerecord->_key_pos[0]._row<3){
                   if(infor->_filerecord->_hitSubstrings.contains("☆"))
                       this->_infors[int(FileToolCode::FTOTAL)].push_back(infor);
            }
            else*/
                this->_infors[int(FileToolCode::FKEY)].push_back(infor);
        }
       // else
        //    this->_infors[int(FileToolCode::FOTHER)].push_back(infor);
        if(infor->_hits[-1]>_totals/2)
            this->_infors[int(FileToolCode::FDOUBT)].push_back(infor);
    }else
    {
        this->_fileinfor.push_back(infor);
        if(record->_filename_flag)
            this->_infors[int(FileToolCode::PTOTAL)].push_back(infor);
        if(infor->_hits[-1]){
            this->_infors[int(FileToolCode::PKEY)].push_back(infor);
            _hitcnts++;
        }
       // else
        //    this->_infors[int(FileToolCode::POTHER)].push_back(infor);
     //   else if(index==JudgeState::Doubt)
        if(infor->_hits[-1]>_totals/2)
            this->_infors[int(FileToolCode::PDOUBT)].push_back(infor);

    }
    _mutex.unlock();

}

bool FileInfor::File_Secret_Flag(QString str){
    bool result=false;
    int pos=str.indexOf("☆");
    int pos1=str.indexOf("★");
    if((pos>=0 && pos <HeadLimit)||(pos1>=0 && pos1 <HeadLimit))
        result = true;
    else{
        for(QString tmp:WarningString)
            if(str.contains(tmp)){
                result = true;
                break;
            }
    }
    return result;
}

void FileInfor::SetFileCheckCondition(const Yzty::FileCheckCondition &condtion)
{
    _mutex.lock();
    this->_filecnts.store(FileFilter::GetInstance()->getAbsfilenumbers());
    Clear();
    _mutex.unlock();
    this->_codition=condtion;
    _totals=0;
    for(int i=0;i<63;++i)
    {
        if((_codition._keywordlimit._marks>>i)&1)
            _totals+=KeyWordLib::GetInstance()->GetKeyWordNums(int64_t(1)<<i); //计算当前检索关键词总数
    }
}

int FileInfor::GetTotalKeyWords()
{
    return  this->_totals;
}

void FileInfor::Clear()
{
    this->_allinfors.clear();
    _infors.clear();
    this->_infors.resize(int(FileToolCode::NUMS));
}


void FileInfor::SwapClassfity(Yzty::MODECODE scode,int index,Yzty::MODECODE pcode){
    Yzty::BaceInfor* temp=_infors[scode][index];
    for(int i=index+1;i<_infors[scode].size();i++)
        _infors[i-1]=_infors[i];
    _infors[pcode].push_back(temp);
}

QVector<Yzty::BaceInfor*>& FileInfor::GetFileReportinfor() {
    return this->_fileinfor;
}
/*
QVector<int> FileInfor::GetFilecnts(){
    return _filecnts;
}

void FileInfor::Initcnts(){
    for(int i=0;i<_filecnts.size();i++)
        _filecnts[i]=0;
    _filecnts[0]=FileFilter::GetInstance()->getAbsfilenumbers();
}
*/
void FileInfor::Resetcnts(){
    this->_checkcnts.store(0);
    this->_hitcnts.store(0);
}

int FileInfor::GetHitcnts(){
    return _hitcnts;
}
int FileInfor::GetFilecnts(){
    return _filecnts;
}
int FileInfor::GetCheckcnts(){
    return _checkcnts;
}
void FileInfor::SetFilecnts(int cnts){
    this->_filecnts.store(cnts);
}
void FileInfor::SetNewFileInfor(const Yzty::FileLevelPerson infor, int indexi, int indexj) {
    Yzty::FileRecordInfor *temp_infor = (Yzty::FileRecordInfor*)_infors[indexi][indexj];
    temp_infor->_pwlevel = infor._pwlevel;
    temp_infor->_evaluator = infor._levelper;
    temp_infor->_descripe = infor._remarks;
    _mutex.lock();
    _infors[indexi][indexj] = temp_infor;
    _mutex.unlock();
}
void FileInfor::AddByperson(int i,Yzty::BaceInfor* infor){
    _mutex.lock();
    this->_infors[i].push_back(infor);
    _mutex.unlock();
}

void FileInfor::removeByPerson(int i, Yzty::BaceInfor *infor){
    _mutex.lock();
    this->_infors[i].removeOne(infor);
    _mutex.unlock();
}
